<?php

//JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_FORCE_OBJECT
if (!defined('JSON_HEX_QUOT'))
{
	define('JSON_HEX_TAG', 1);
	define('JSON_HEX_AMP', 2);
	define('JSON_HEX_APOS', 4);
	define('JSON_HEX_QUOT', 8);
	define('JSON_FORCE_OBJECT', 16);
}

define('JSON_FORCE_UTF', 512);

class Mozg_Lib_Json implements Mozg_Lib
{
	protected function PrepareVal($val, $options)
	{
		switch (gettype($val))
		{
			case "array":
			case "object":
				foreach ($val as &$v)
				{
					$v = $this->PrepareVal($v, $options);
				}

				if ($options & JSON_FORCE_OBJECT)
				{
					$val = (object)$val;
				}
				break;

		}

		return $val;
	}

	public function Encode($value, $options = 0)
	{
		if ($options & JSON_FORCE_OBJECT)
		{
			$value = $this->PrepareVal($value, $options);
		}

		$result = json_encode($value);

		if ($options & JSON_FORCE_UTF)
		{
			$result = $this->UnescapeUTF($result);
		}

		$replaceChars = $replaceCharsTo = array();

		if ($options & JSON_HEX_TAG)
		{
			$replaceChars[] = '<';$replaceChars[] = '>';
			$replaceCharsTo[] = '\u003C';$replaceCharsTo[] = '\u003E';
		}

		if ($options & JSON_HEX_AMP)
		{
			$replaceChars[] = '&';
			$replaceCharsTo[] = '\u0026';
		}

		if ($options & JSON_HEX_APOS)
		{
			$replaceChars[] = "'";
			$replaceCharsTo[] = '\u0027';
		}

		if (sizeof($replaceChars))
		{
			$result = str_replace($replaceChars, $replaceCharsTo, $result);
		}

		return $result;
	}

	public function Decode($json, $assoc = false/*, $depth = 512, $options = 0*/)
	{
		return json_decode($json, $assoc/*, $depth, $options*/);
	}

	protected function UnescapeUTF($s)
	{
	    if (!is_string($s) || strpos($s, '\u') === false) return $s; #use strpos() for speed improving
	    return preg_replace_callback('#\\\u([\da-fA-F]{4})#sS', array($this, 'UnescapeChar'), $s);
	}

	public function UnescapeChar(array $m)
	{
		return iconv("UCS-2","UTF-8", pack("v*", hexdec($m[1])));
	}
}